using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Windows.Forms;
using Microsoft.Win32;
using EA;

namespace OpenEdge
{
	public class EAAddin
	{
		protected DatabaseEngineering.Generate.Application				DBGenerateApp;
		protected DatabaseEngineering.Import.Application				DBImportApp;
		protected DatabaseEngineering.Import.OptionsForm				myOptionsForm;

		private bool m_ShowFullMenus = false;

		public EAAddin()
		{
			
		}

		//Called Before EA starts to check Add-In Exists
		public String EA_Connect(EA.Repository Repository)
		{
			//No special processing required.

			return "a string";
			
		}

		public void EA_Disconnect()  
		{
			GC.Collect();  
			GC.WaitForPendingFinalizers();   
		}


		//Called when user Click Add-Ins Menu item from within EA.
		//Populates the Menu with our desired selections.
		public object EA_GetMenuItems(EA.Repository Repository, string Location, string MenuName) 
		{			
			switch( MenuName )
			{
				case "":
					return "-&OpenEdge";
				case "-&OpenEdge":
					if( IsProjectOpen(Repository) && Repository.IsTechnologyLoaded("OpenEdge"))
					{
						string objectType = Repository.GetContextItemType().ToString();

                        Object currentObject = null;
						Repository.GetContextItem(out currentObject);

						switch(objectType)
						{
							case "otPackage":
								EA.Package currentPackage = (EA.Package) currentObject;
								currentPackage = Repository.GetPackageByID(currentPackage.PackageID);
								switch(currentPackage.Element.Stereotype)
								{
									case "database":
									{										
										string[] b = {
													    "Ge&nerate Schema Definition File...",
													    "I&mport Schema Definition File...",
													    "&Create Package Diagram",
													    "-",
													    "Help",
													    "About" };										
										return b;
									}
                                    default:
                                    {
                                        string[] c = {
														"I&mport Schema Definition File...",
														"-",
														"&Create Package Diagram",
														"-",
														"Help",
														"About" };
                                        return c;
                                    }
								}
							case "otElement":
								
								EA.Element currentElement = (EA.Element) currentObject;
								currentElement = Repository.GetElementByID(currentElement.ElementID);
								switch(currentElement.Stereotype)
								{
									case "Dataset":
										string[] a = {
														 "Help",
														 "About" };
										return a;
									default:
										break;
								}								
								break;
							case "otDiagram":
                                EA.Diagram currentDiagram = (EA.Diagram)currentObject;
								break;
							case "otAttribute":
								EA.Attribute currentAttribute = (EA.Attribute) currentObject;
								break;
							case "otMethod":
                                EA.Method currentMethod = (EA.Method)currentObject;
								break;
							case "otConnector":
								EA.Connector currentConnector = (EA.Connector) currentObject;
								currentConnector = Repository.GetConnectorByID(currentConnector.ConnectorID);
								break;
							default:
								break;
						}
					}
					else
					{
						string[] aa = {
                                        "&Install MDG Technology for OpenEdge",
										"-",
										"Help",
										"About" };
						return aa;
					}
                    break;
				default:
					break;
			}
			return "";

		}

		bool IsProjectOpen(EA.Repository Repository)
		{
			try
			{
				EA.Collection c = Repository.Models;
				return true;
			}
			catch
			{
				return false;
			}
		}

		//Called once Menu has been opened to see what menu items are active.
		public void EA_GetMenuState(EA.Repository Repository, string Location, string MenuName, string ItemName, ref bool IsEnabled, ref bool IsChecked)
		{
			if( IsProjectOpen(Repository) )
			{
				if( ItemName == "Menu1" )
					IsChecked = m_ShowFullMenus;
				else if( ItemName == "Menu2")
					IsEnabled = m_ShowFullMenus;
			}
			else
				// If no open project, disable all menu options
				IsEnabled = false;
		}

		//Called when user makes a selection in the menu.
		//This is your main exit point to the rest of your Add-in
		public void EA_MenuClick(EA.Repository Repository, string Location, string MenuName, string ItemName)
		{						
			switch( ItemName )
			{
				case "Ge&nerate Schema Definition File...":
					this.DBGenerateApp = new DatabaseEngineering.Generate.Application(Repository);
					this.DBGenerateApp.showOptionsForm();
					break;
				case "I&mport Schema Definition File...":
					this.DBImportApp = new DatabaseEngineering.Import.Application(Repository);
					this.DBImportApp.showOptionsForm();
					break;
				case "&Create Package Diagram":
					this.DBImportApp = new DatabaseEngineering.Import.Application(Repository);
					this.DBImportApp.createSchemaDiagram();
					break;
				case "&Install MDG Technology for OpenEdge":
					RegistryKey hklm			= Registry.CurrentUser;
					RegistryKey hkSoftware		= hklm.OpenSubKey("Software");
					RegistryKey hkSparxSystems	= hkSoftware.OpenSubKey("Sparx Systems");
					RegistryKey hkEAAddins      = hkSparxSystems.OpenSubKey("EAAddins");
					RegistryKey hkOpenEdge		= hkEAAddins.OpenSubKey("OpenEdge");

					FileStream fs		= new FileStream((string) hkOpenEdge.GetValue("MDGTPath"),
						FileMode.Open,
						FileAccess.Read,
						FileShare.Read);

					StreamReader sr		= new StreamReader(fs);
					string technologyString = "";
                    technologyString = sr.ReadToEnd();
					sr.Close();
					fs.Close();
					Repository.ImportTechnology(technologyString);
					break;
				case "Help":
					MessageBox.Show("If you need help, then contact pmagnay@progress.com", "Help");
					break;
				case "About":
					MessageBox.Show("If you would like to learn more, then contact pmagnay@progress.com", "About");
					break;
			}

		}


		public String GetTTRelationshipsForDataset(EA.Repository repository, Object classGUID)
		{
			
			String[]	guid = (String[])classGUID;
			String		returnString = "";

			EA.Element currentElement = (EA.Element) repository.GetElementByGuid(guid[0].ToString());

			EA.Diagram currentDiagram = null;
			ArrayList  dsTemptables = new ArrayList();
			ArrayList  dsRelations  = new ArrayList();

			for (short idx = 0; idx < currentElement.Diagrams.Count; idx++) 
			{
				EA.Diagram childDiagram = (EA.Diagram) currentElement.Diagrams.GetAt(idx); 
				if (childDiagram.Name == currentElement.Name)
				{
					currentDiagram = childDiagram;
					break;
				}
			}
			if (currentDiagram != null) 
			{
				for (short idx = 0; idx < currentDiagram.DiagramObjects.Count; idx++) 
				{
					EA.DiagramObject diagramObject = (DiagramObject) currentDiagram.DiagramObjects.GetAt(idx);
					EA.Element diagramElement = (Element) repository.GetElementByID(diagramObject.ElementID);
					if (diagramElement.Type == "Class" && diagramElement.Stereotype == "table")
						dsTemptables.Add(diagramElement);

				}
			}
				
			if (dsTemptables.Count > 0) 
			{

				for (short idx = 0; idx < currentDiagram.DiagramLinks.Count; idx++) 
				{
					EA.DiagramLink diagramLink = (EA.DiagramLink) currentDiagram.DiagramLinks.GetAt(idx);					

					if (diagramLink.IsHidden)
						continue;

					EA.Connector diagramConnector = (EA.Connector) repository.GetConnectorByID(diagramLink.ConnectorID);

					if (diagramConnector.Stereotype != "FK")
						continue;

					EA.Element supplierElement = repository.GetElementByID(diagramConnector.SupplierID);
					EA.Element clientElement = repository.GetElementByID(diagramConnector.ClientID);

					returnString += "\tDATA-RELATION ";
					returnString += diagramConnector.Name;
					returnString += " FOR ";
					returnString += supplierElement.Name;
					returnString += ",";
					returnString += clientElement.Name;
					
					EA.ConnectorEnd supplierEnd = diagramConnector.SupplierEnd;
					EA.Method supplierMethod = null;
					for (short j = 0; j < supplierElement.Methods.Count; j++) 
					{
						supplierMethod = (EA.Method) supplierElement.Methods.GetAt(j);
						if (supplierMethod.Name == supplierEnd.Role)
							break;
					}

					EA.ConnectorEnd clientEnd = diagramConnector.ClientEnd;
					EA.Method clientMethod = null;
					for (short j = 0; j < clientElement.Methods.Count; j++) 
					{
						clientMethod = (EA.Method) clientElement.Methods.GetAt(j);
						if (clientMethod.Name == clientEnd.Role)
							break;
					}

					returnString += "\n\t\tRELATION-FIELDS (";
					for (short j = 0; j < supplierMethod.Parameters.Count; j++)
					{
						EA.Parameter supplierParameter = (EA.Parameter) supplierMethod.Parameters.GetAt(j);

						EA.Parameter clientParameter = (EA.Parameter) clientMethod.Parameters.GetAt(j);

						returnString += supplierParameter.Name;
						returnString += ",";
						returnString += clientParameter.Name;
						if (j < supplierMethod.Parameters.Count - 1)
							returnString += ",";
					}
					returnString += ")\n";

				}

			}


			return returnString;

		}


        public String GetDataSourceBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Collection dsCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "DataSource");

                foreach (EA.Element dsElement in dsCollection)
                {
                    if (dsElement.Stereotype == "DataSource")
                    {
                        returnString = dsElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetDataSourceBase -- " + exception, "GetDataSourceBase Exception");
                returnString = "";
            }

            return returnString;

        }

					
		public String GetDataSourceDec(EA.Repository repository, Object classGUID)
		{

			String[]	guid = (String[])classGUID;
			String		returnString = "";

			EA.Element currentElement = (EA.Element) repository.GetElementByGuid(guid[0].ToString());

			EA.Element   tableElement = null;
			
			for (short idx = 0; idx < currentElement.Connectors.Count; idx++) 
			{
				
				EA.Connector dataConnector = (EA.Connector) currentElement.Connectors.GetAt(idx);
				if (dataConnector.Stereotype.Equals("DATASOURCE")) 
				{
					if (dataConnector.ClientID != currentElement.ElementID) 
					{
						tableElement = repository.GetElementByID(dataConnector.ClientID);
						break;
					}
					else
					{
						tableElement = repository.GetElementByID(dataConnector.SupplierID);
						break;
					}
					
				}
			}

			
			EA.Method constructorMethod = null;
			for (short idx = 0; idx < currentElement.Methods.Count; idx++) 
			{
				constructorMethod = (EA.Method) currentElement.Methods.GetAt(idx);

				if (constructorMethod.Name == currentElement.Name) 
					break;
			}

			if (constructorMethod != null) 
			{
				for (short idx = 0; idx < constructorMethod.Parameters.Count; idx++) 
				{
					EA.Parameter methodParameter = (EA.Parameter) constructorMethod.Parameters.GetAt(idx);

					returnString += this.processParameter(methodParameter);

				}
				returnString += "\n";
			}

			// bool queryPrepareFound = false;
            bool dataMappingFound  = false;
            bool datasetPreferFound = false;
            bool mergeByFieldFound  = false;
			for (short idx = 0; idx < currentElement.Attributes.Count; idx++) 
			{
				EA.Attribute currentAttribute = (EA.Attribute) currentElement.Attributes.GetAt(idx);
					
				returnString += "DEFINE VARIABLE " + currentAttribute.Name + " AS " + currentAttribute.Type;
				if (currentAttribute.Default.Length > 0)
					returnString += " INITIAL \"" + currentAttribute.Default + "\"";
				else
				if (currentAttribute.Type == "LOGICAL")
					returnString += " INITIAL ?";
				else
				if (currentAttribute.Type == "CHARACTER")
					returnString += " INITIAL \"\"";

				returnString += " NO-UNDO.\n";

   				if (currentAttribute.Name == "vcDataMapping")
					dataMappingFound = true;

   				if (currentAttribute.Name == "vlDatasetPrefer")
					datasetPreferFound = true;

   				if (currentAttribute.Name == "vlMergeByField")
					mergeByFieldFound = true;

				// if (currentAttribute.Name == "queryPrepare")
					//queryPrepareFound = true;


				if (idx == currentElement.Attributes.Count - 1)
					returnString += "\n";
			}			


			ArrayList dbtableElements = new ArrayList();
			for (short idx = 0; idx < currentElement.Connectors.Count; idx++) 
			{
				
				EA.Connector dataConnector = (EA.Connector) currentElement.Connectors.GetAt(idx);
				if (dataConnector.Stereotype.Equals("DATABASE")) 
				{
					if (dataConnector.ClientID != currentElement.ElementID) 
					{
						EA.Element currentDBElement = repository.GetElementByID(dataConnector.ClientID);
                        dbtableElements.Add(currentDBElement);
					}
					else
					{
						EA.Element currentDBElement = repository.GetElementByID(dataConnector.SupplierID);
						dbtableElements.Add(currentDBElement);
					}
					
				}
			}

			if (dbtableElements.Count > 0)
			{

				EA.Element dbElement = (EA.Element) dbtableElements[0];

				returnString += "DEFINE QUERY qry";
				returnString += dbElement.Name;
				returnString += " FOR ";
				returnString += dbElement.Name;

				for (int idx = 1; idx < dbtableElements.Count; idx++)
				{
					EA.Element joinElement = (EA.Element) dbtableElements[idx];
					returnString += ", " + joinElement.Name;
				}
				returnString += ".\n";
                returnString += "\n";

				returnString += "DEFINE DATA-SOURCE src";
				returnString += dbElement.Name;
				returnString += " FOR QUERY qry";
                //returnString += " FOR ";
				returnString += dbElement.Name;
                returnString += " " + dbElement.Name + " KEYS(ROWID)";
				returnString += ".\n";
				returnString += "\n";

                /*
				if (queryPrepareFound)
				{
					returnString += "IF queryPrepare NE \"\" THEN\n";
					returnString += "\tQUERY qry" + dbElement.Name + ":QUERY-PREPARE(queryPrepare).\n";
					returnString += "\n";
				}
                 */

                returnString += "ASSIGN\n";

                if (dataMappingFound)
                {
                    returnString += "\t";
                    returnString += "vcDataMapping = \" ROWID(" + dbElement.Name + ")," + dbElement.Name + "RowID\"\n";
                }

                if (datasetPreferFound)
                {
                    returnString += "\t";
                    returnString += "DATA-SOURCE src" + dbElement.Name + ":HANDLE:PREFER-DATASET = vlDatasetPrefer\n";                    
                }

                if (mergeByFieldFound)
                {
                    returnString += "\t";
                    returnString += "DATA-SOURCE src" + dbElement.Name + ":HANDLE:MERGE-BY-FIELD = vlMergeByField\n";                    
                }

                returnString += "\t.\n";
                returnString += "\n";

				returnString += "iphbuffer:ATTACH-DATA-SOURCE(DATA-SOURCE src" + dbElement.Name;
				returnString += ":HANDLE, vcDataMapping).\n";

			}

			return returnString;
		}

        public String GetBusinessLogicBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Collection blCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "blSuper");

                foreach (EA.Element blElement in blCollection)
                {
                    if (blElement.Stereotype == "BusinessLogic")
                    {
                        returnString = blElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetBusinessLogicBase -- " + exception, "GetBusinessLogicBase Exception");
                returnString = "";
            }

            return returnString;

        }

        public String GetDataAccessBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Collection daCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "daSuper");

                foreach (EA.Element daElement in daCollection)
                {
                    if (daElement.Stereotype == "DataAccess")
                    {
                        returnString = daElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetDataAccessBase -- " + exception, "GetDataAccessBase Exception");
                returnString = "";
            }

            return returnString;

        }


        public String GetTranProcBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Collection tpCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "TranProc");

                foreach (EA.Element tpElement in tpCollection)
                {
                    if (tpElement.Stereotype == "TranProc")
                    {
                        returnString = tpElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetTranProcBase -- " + exception, "GetTranProcBase Exception");
                returnString = "";
            }

            return returnString;

        }

        public String GetBufferProxyBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Package modelPackage = (EA.Package)repository.Models.GetAt(0);
                if (modelPackage == null)
                    return returnString;

                EA.Package designViewPackage = (EA.Package)modelPackage.Packages.GetByName("Design View");
                if (designViewPackage == null)
                    return returnString;

                EA.Package comPackage = (EA.Package)designViewPackage.Packages.GetByName("erp");
                if (comPackage == null)
                    return returnString;

                EA.Package dandhPackage = (EA.Package)comPackage.Packages.GetByName("client");
                if (dandhPackage == null)
                    return returnString;

                EA.Package basePackage = (EA.Package)dandhPackage.Packages.GetByName("common");
                if (basePackage == null)
                    return returnString;

                EA.Element foundElement = (EA.Element)basePackage.Elements.GetByName("ProxyBase");
                if (foundElement == null)
                    return returnString;

                returnString = foundElement.ElementGUID;
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetBufferProxyBase -- " + exception, "GetBufferProxyBase Exception");
                returnString = "";
            }

            return returnString;

        }

        public String GetTTControlBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {
                EA.Collection ttCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "TTControlBase");

                foreach (EA.Element ttElement in ttCollection)
                {
                    if (ttElement.Stereotype == "TTControl")
                    {
                        returnString = ttElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetTTControlBase -- " + exception, "GetTTControlBase Exception");
                returnString = "";
            }

            return returnString;

        }

        
        public String GetTTControlGUID(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String searchString = args[0].ToString();
            String returnString = "";

            searchString = searchString + "Control";

            EA.Collection ttCollection = (EA.Collection)repository.GetElementsByQuery("Simple", searchString);


            foreach (EA.Element ttElement in ttCollection)
            {

                if (ttElement.Stereotype == "TTControl")
                    returnString = ttElement.ElementGUID;
            }


            return returnString;

        }

        public String GetBufferProxyGUID(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String searchString = args[0].ToString();
            String returnString = "";

            searchString = searchString + "Proxy";

            EA.Collection ttCollection = (EA.Collection)repository.GetElementsByQuery("Simple", searchString);


            foreach (EA.Element ttElement in ttCollection)
            {

                if (ttElement.Stereotype == "BufferProxy")
                    returnString = ttElement.ElementGUID;
            }


            return returnString;

        }


		private String processParameter(Parameter currentParameter) 
		{

			String returnString = "DEFINE ";
			switch(currentParameter.Kind)
			{
				case "in":
					returnString += "INPUT ";
					break;
				case "out":
					returnString += "OUTPUT ";
					break;
				case "inout":
					returnString += "INPUT-OUTPUT ";
					break;
				default:
					returnString += "INPUT ";
					break;
			}
			returnString += "PARAMETER ";
			if (currentParameter.Type == "DATASET") 
			{
				returnString += "DATASET FOR ";
				returnString += currentParameter.Name;
				returnString += ".";
			}
			else
			{
				returnString += currentParameter.Name;
				returnString += " AS ";
				returnString += currentParameter.Type;
				returnString += " NO-UNDO.\n";
			}

			return returnString;

		}

        public String GetFirstTTName(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            int pdsElementID = 0;
            int ttElementID  = 0;
            String ttName  = "";

            EA.Element classElement = (EA.Element) repository.GetElementByGuid(args[0].ToString());

            foreach (EA.Connector classConnector in classElement.Connectors)
            {
                if (classConnector.Stereotype == "DATASET")
                {
                    pdsElementID = classConnector.ClientID;                    
                    break;
                }
            }

            if (pdsElementID != 0)
            {
                EA.Element pdsElement = (EA.Element)repository.GetElementByID(pdsElementID);
                foreach (EA.Connector pdsConnector in pdsElement.Connectors)
                {
                    if (pdsConnector.Stereotype == "DATATABLE")
                    {
                        ttElementID = pdsConnector.ClientID; 
                        break;
                    }
                }

                if (ttElementID != 0)
                {
                    EA.Element ttElement = (EA.Element)repository.GetElementByID(ttElementID);
                    ttName = ttElement.Name;
                }
            }

            return ttName;

        }


        public String GetTTGUID (EA.Repository repository, Object inArgs)
        {
            String[] args = (String[]) inArgs;
            String returnString = "";

            
            EA.Collection ttCollection = (EA.Collection) repository.GetElementsByQuery("Simple","ttbl" + args[0].ToString());

            
            foreach (EA.Element ttElement in ttCollection)
            {

                if (ttElement.Name == ("ttbl" + args[0].ToString()))
                    returnString = ttElement.ElementGUID;
            }
            

            return returnString;

        }

		public String GetTTInclude(EA.Repository repository, Object connectorGUID)
		{
			String[]	guid = (String[])connectorGUID;
			String		returnString = "";

			EA.Connector currentConnector = (EA.Connector) repository.GetConnectorByGuid(guid[0].ToString());
			
			if (currentConnector != null)
			{
				EA.Element connectedElement = (EA.Element) repository.GetElementByID(currentConnector.ClientID);
				if (connectedElement != null && connectedElement.Stereotype == "table")
				{
					returnString = connectedElement.Genfile.Substring(connectedElement.Genfile.LastIndexOf(@"\") + 1);
                    string nspacePath = "";
                    // getNspacePath(nspacePath, repository, connectedElement.PackageID, out nspacePath);
                    returnString = nspacePath + connectedElement.Genfile.Substring(connectedElement.Genfile.LastIndexOf(@"\") + 1);


				}
				//else
					//returnString = "null element";
			}
			else
				returnString = "null";

			return returnString;

		}


        public String GetDatasetBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {

                EA.Collection dstCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "DataSet");

                foreach (EA.Element dstElement in dstCollection)
                {
                    if (dstElement.Stereotype == "DataSet")
                    {
                        returnString = dstElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetDatasetBase -- " + exception, "GetDatasetBase Exception");
                returnString = "";
            }

            return returnString;

        }

        public String GetSABase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {

                EA.Collection dstCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "ServiceAdapter");

                foreach (EA.Element dstElement in dstCollection)
                {
                    if (dstElement.Stereotype == "ServiceAdapter")
                    {
                        returnString = dstElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetSABase -- " + exception, "GetSABase Exception");
                returnString = "";
            }

            return returnString;

        }

        public String GetUTBase(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            try
            {

                EA.Collection utCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "utSuper");

                foreach (EA.Element utElement in utCollection)
                {
                    if (utElement.Stereotype == "UnitTest")
                    {
                        returnString = utElement.ElementGUID;
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show("GetUTBase -- " + exception, "GetUTBase Exception");
                returnString = "";
            }

            return returnString;

        }



		public String GetDatasetInclude(EA.Repository repository, Object connectorGUID)
		{
			String[]	guid = (String[])connectorGUID;
			String		returnString = "";

			EA.Connector currentConnector = (EA.Connector) repository.GetConnectorByGuid(guid[0].ToString());
			
			if (currentConnector != null)
			{
				EA.Element connectedElement = (EA.Element) repository.GetElementByID(currentConnector.ClientID);
				if (connectedElement != null && connectedElement.Stereotype == "DataSet")
				{
					//string nspacePath = "";
					// getNspacePath(nspacePath, repository, connectedElement.PackageID, out nspacePath);
					// returnString = "{" + nspacePath + connectedElement.Genfile.Substring(connectedElement.Genfile.LastIndexOf(@"\") + 1) + "}";
                    returnString = connectedElement.Genfile.Substring(connectedElement.Genfile.LastIndexOf(@"\") + 1);
				}
				else
				    returnString = connectedElement.Name;
			}
			else
				returnString = "null";

			return returnString;

		}

		public String GetDatasetReference(EA.Repository repository, Object connectorGUID)
		{
			String[]	guid = (String[])connectorGUID;
			String		returnString = "";

			EA.Connector currentConnector = (EA.Connector) repository.GetConnectorByGuid(guid[0].ToString());
			
			if (currentConnector != null)
			{
				EA.Element connectedElement = (EA.Element) repository.GetElementByID(currentConnector.SupplierID);
				if (connectedElement != null && connectedElement.Stereotype == "Dataset")
				{
					string nspacePath = "";
					getNspacePath(nspacePath, repository, connectedElement.PackageID, out nspacePath);
					returnString = "{" + nspacePath + connectedElement.Genfile.Substring(connectedElement.Genfile.LastIndexOf(@"\") + 1) + " &REFERENCE-ONLY=REFERENCE-ONLY}";
				}
				//else
				//returnString = "null element";
			}
			else
				returnString = "null";

			return returnString;

		}

		public String GetParamStereotype(EA.Repository repository, Object GUIDList)
		{
			String[]	guidList      = (String[])GUIDList;
			String      methodGUID    = guidList[0];
			String      parameterGUID = guidList[1];
			String		returnString  = "";

			EA.Method currentMethod = (EA.Method) repository.GetMethodByGuid(methodGUID);			
			
			if (currentMethod != null)
			{
				foreach(EA.Parameter currentParameter in currentMethod.Parameters)
				{
					if (currentParameter.ParameterGUID == parameterGUID)
					{
						returnString = currentParameter.Stereotype;
						break;
					}
				}
			}
			else
				returnString = "null";

			return returnString;

		}

        public String GetPackagePath(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";

            EA.Element currentElement = (EA.Element)repository.GetElementByGuid(args[0].ToString());
            
            getNspacePath2(returnString, repository, currentElement.PackageID, out returnString);
            
            return returnString;

        }

        private void getNspacePath2(String inPath, EA.Repository repository, int packageID, out String returnString)
        {
            EA.Package thisPackage = (EA.Package)repository.GetPackageByID(packageID);
            if (!thisPackage.IsNamespace)
            {
                string nspacePath = thisPackage.Name + "." + inPath;
                getNspacePath2(nspacePath, repository, thisPackage.ParentID, out nspacePath);
                returnString = nspacePath;
            }
            else
                returnString = inPath;

        }

		private void getNspacePath(String inPath, EA.Repository repository, int packageID, out String returnString)
		{			
			EA.Package thisPackage = (EA.Package) repository.GetPackageByID(packageID);
			if (!thisPackage.IsNamespace)
			{
				string nspacePath = thisPackage.Name + "/" + inPath;
				getNspacePath(nspacePath, repository, thisPackage.ParentID, out nspacePath);
				returnString = nspacePath;
			}
			else
				returnString = inPath;

		}


        public String SetDSDiagram(EA.Repository repository, Object classGUID)
        {
            String[] guid = (String[])classGUID;
            String returnString = "";

            EA.Element currentElement = (EA.Element)repository.GetElementByGuid(guid[0].ToString());

            currentElement.Diagrams.AddNew(currentElement.Name, "Class");
            currentElement.Update();

            return returnString;

        }

        public String GetTranProcCode(EA.Repository repository, Object inArgs)
        {
            String[] args = (String[])inArgs;
            String returnString = "";
            String tableName = "";
            String dbTableName = "";
            String procName  = "";
            String whereString = "";

            EA.Element tableElement = (EA.Element)repository.GetElementByGuid(args[0].ToString());
            tableName = tableElement.Name;
            dbTableName = tableName.Substring(4);
            procName = args[1].ToString().Replace(tableName, "");

            switch (procName)
            {
                case "CreatePreTrans":
                    {
                        returnString = "\n\tDEFINE VARIABLE cRtnVal      AS CHARACTER NO-UNDO.\n\n";

                        foreach (EA.Method thisMethod in tableElement.Methods)
                        {
                            if (thisMethod.Stereotype == "PK")
                            {
                                returnString = returnString + "\tFIND FIRST " + dbTableName + " NO-LOCK\n\t\tWHERE ";
                                whereString = "";
                                foreach (EA.Parameter thisParameter in thisMethod.Parameters)
                                {
                                    if (whereString != "")
                                    {
                                        whereString = whereString + "\n\t\tAND ";
                                    }
                                    whereString = whereString +
                                        dbTableName + "." + thisParameter.Name + " = " + tableName + "." + thisParameter.Name;
                                }

                                returnString = returnString + whereString + "\n\t\tNO-ERROR." +
                                               "\n\tIF AVAILABLE " + dbTableName + " THEN" +
                                               "\n\tDO:" +
                                               "\n\t\tASSIGN cRtnVal = \"Duplicate primary key violation on create!\"" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR = TRUE" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR-STRING = cRtnVal." +
                                               "\n\t\tRETURN." +
                                               "\n\tEND." +
                                               "\n\n\n";

                            }

                            if (thisMethod.Stereotype == "unique")
                            {
                                returnString = returnString + "\tFIND FIRST " + dbTableName + " NO-LOCK\n\t\tWHERE ";
                                whereString = "";
                                foreach (EA.Parameter thisParameter in thisMethod.Parameters)
                                {
                                    if (whereString != "")
                                    {
                                        whereString = whereString + "\n\t\tAND ";
                                    }
                                    whereString = whereString +
                                        dbTableName + "." + thisParameter.Name + " = " + tableName + "." + thisParameter.Name;
                                }

                                returnString = returnString + whereString + "\n\t\tNO-ERROR." +
                                               "\n\tIF AVAILABLE " + dbTableName + " THEN" +
                                               "\n\tDO:" +
                                               "\n\t\tASSIGN cRtnVal = \"Unique key violation on create!\"" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR = TRUE" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR-STRING = cRtnVal." +
                                               "\n\t\tRETURN." +
                                               "\n\tEND." +
                                               "\n\n\n";
                                
                            }
                        }
                    }
                    break;
                case "CreateBeginTrans":
                    returnString = "";
                    break;
                case "CreateEndTrans":
                    returnString = "";
                    break;
                case "CreatePostTrans":
                    returnString = "";
                    break;
                case "UpdatePreTrans":
                    {
                        returnString = "\n\tDEFINE VARIABLE cRtnVal      AS CHARACTER NO-UNDO.\n\n";

                        foreach (EA.Method thisMethod in tableElement.Methods)
                        {
                            if (thisMethod.Stereotype == "PK")
                            {
                                returnString = returnString + "\tFIND FIRST " + dbTableName + " NO-LOCK\n\t\tWHERE ";
                                whereString = "";
                                foreach (EA.Parameter thisParameter in thisMethod.Parameters)
                                {
                                    if (whereString != "")
                                    {
                                        whereString = whereString + "\n\t\tAND ";
                                    }
                                    whereString = whereString +
                                        dbTableName + "." + thisParameter.Name + " = " + tableName + "." + thisParameter.Name;
                                }
                                if (whereString != "")
                                {
                                    whereString = whereString + "\n\t\tAND ROWID(" + dbTableName + ") NE " + tableName + "." + dbTableName + "Rowid";
                                }

                                returnString = returnString + whereString + "\n\t\tNO-ERROR." +
                                               "\n\tIF AVAILABLE " + dbTableName + " THEN" +
                                               "\n\tDO:" +
                                               "\n\t\tASSIGN cRtnVal = \"Duplicate primary key violation on update!\"" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR = TRUE" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR-STRING = cRtnVal." +
                                               "\n\t\tRETURN." +
                                               "\n\tEND." +
                                               "\n\n\n";

                            }

                            if (thisMethod.Stereotype == "unique")
                            {
                                returnString = returnString + "\tFIND FIRST " + dbTableName + " NO-LOCK\n\t\tWHERE ";
                                whereString = "";
                                foreach (EA.Parameter thisParameter in thisMethod.Parameters)
                                {
                                    if (whereString != "")
                                    {
                                        whereString = whereString + "\n\t\tAND ";
                                    }
                                    whereString = whereString +
                                        dbTableName + "." + thisParameter.Name + " = " + tableName + "." + thisParameter.Name;
                                }
                                if (whereString != "")
                                {
                                    whereString = whereString + "\n\t\tAND ROWID(" + dbTableName + ") NE " + tableName + "." + dbTableName + "Rowid";
                                }

                                returnString = returnString + whereString + "\n\t\tNO-ERROR." +
                                               "\n\tIF AVAILABLE " + dbTableName + " THEN" +
                                               "\n\tDO:" +
                                               "\n\t\tASSIGN cRtnVal = \"Unique key violation on update!\"" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR = TRUE" +
                                               "\n\t\tBUFFER " + tableName + "before:HANDLE:ERROR-STRING = cRtnVal." +
                                               "\n\t\tRETURN." +
                                               "\n\tEND." +
                                               "\n\n\n";

                            }
                        }
                    }
                    break;
                case "UpdateBeginTrans":
                    returnString = "";
                    break;
                case "UpdateEndTrans":
                    returnString = "";
                    break;
                case "UpdatePostTrans":
                    returnString = "";
                    break;
                case "DeletePreTrans":
                    returnString = "";
                    break;
                case "DeleteBeginTrans":
                    returnString = "";
                    break;
                case "DeleteEndTrans":
                    returnString = "";
                    break;
                case "DeletePostTrans":
                    returnString = "";
                    break;
                default:
                    returnString = "";
                    break;
            }


            return returnString;

        }

		public String GetTTBase(EA.Repository repository, Object inArgs)
		{
            String[] args         = (String[])inArgs;
			String	 returnString = "";

			try 
			{

                EA.Collection ttCollection = (EA.Collection)repository.GetElementsByQuery("Simple", "TempTable");

                foreach (EA.Element ttElement in ttCollection)
                {
                    if (ttElement.Stereotype == "table")
                    {
                        returnString = ttElement.ElementGUID;
                        break;
                    }
                }

			}
			catch(Exception exception)
			{
                MessageBox.Show("GetTTBase -- " + exception, "GetTTBase Exception");
				returnString = "";
			}

            return returnString;
        }

		public String GetMethodOverride(EA.Repository repository, Object opGUID)
		{
			String[]	guid = (String[])opGUID;
			String		returnString = "";

			EA.Method currentMethod = (EA.Method) repository.GetMethodByGuid(guid[0].ToString());
			
			if (currentMethod != null)
			{
				EA.Element methodElement = (EA.Element) repository.GetElementByID(currentMethod.ParentID);

				if (methodElement != null)
				{
					foreach(EA.Connector connector in methodElement.Connectors)
					{
						if ((connector.ClientID == methodElement.ElementID) && (connector.Type == "Generalization"))
						{
							EA.Element superElement = (EA.Element) repository.GetElementByID(connector.SupplierID);
							
							foreach(EA.Method superMethod in superElement.MethodsEx)
							{
								if ((superMethod.Name == currentMethod.Name) &&
									(superMethod.ReturnType == currentMethod.ReturnType))
								{
									bool parameterMatch = false;
									if ((currentMethod.Parameters.Count == 0) && (superMethod.Parameters.Count == 0))
										parameterMatch = true;
									else
									{										
										foreach(EA.Parameter currentParameter in currentMethod.Parameters)
										{
											EA.Parameter superParameter = (EA.Parameter) superMethod.Parameters.GetByName(currentParameter.Name);
											if ((superParameter != null) && 
												(superParameter.Type == currentParameter.Type) &&
												(superParameter.Kind == currentParameter.Kind))
											{
												parameterMatch = true;
											}
											else
											{
												parameterMatch = false;
												break;
											}
										}
									}
									if (parameterMatch) 
										returnString = "OVERRIDE";
									else
										returnString = "Parameter mismatch";

									break;
								}
								else
									returnString = "superMethod not found";

							}

							break;
						}

					}
				}
			}
			else
				returnString = "null";

			return returnString;
		}

		public EA.Element parsePackage(EA.Package currentPackage, String searchName)
		{

			EA.Element returnElement = null;

			for (short idx = 0; idx < currentPackage.Packages.Count; idx++)
			{
				returnElement = parsePackage((EA.Package)currentPackage.Packages.GetAt(idx), searchName);
				if (returnElement != null)
					return returnElement;
			}

			for (short idx = 0; idx < currentPackage.Elements.Count; idx++)
			{
				EA.Element currentElement = (EA.Element) currentPackage.Elements.GetAt(idx);
				if (currentElement.Name == searchName)
					return currentElement;
			}

			return null;
		}

		public String CreateDataSetDiagram(EA.Repository repository, Object classGUID)
		{
			String[]	guid = (String[])classGUID;
			String		returnString = "";

			try
			{
				repository.EnableUIUpdates = false;

				EA.Element currentElement = (EA.Element) repository.GetElementByGuid(guid[0].ToString());			
				EA.Diagram currentDiagram = (EA.Diagram) currentElement.Diagrams.AddNew(currentElement.Name,"Class");
				currentDiagram.ShowDetails = 0;
				currentDiagram.Update();
				currentElement.Diagrams.Refresh();

				EA.DiagramObject currentDiagramObject = (EA.DiagramObject) currentDiagram.DiagramObjects.AddNew("","");
				currentDiagramObject.ElementID = currentElement.ElementID;
				currentDiagramObject.Update();

				foreach (EA.Connector currentConnector in currentElement.Connectors) 
				{
					if (currentConnector.Stereotype == "DATATABLE")
					{
						EA.Element ttElement = (EA.Element) repository.GetElementByID(currentConnector.ClientID);
						if (ttElement != null)
						{
							EA.DiagramObject ttDiagramObject = (EA.DiagramObject) currentDiagram.DiagramObjects.AddNew("","");
							ttDiagramObject.ElementID = ttElement.ElementID;
							ttDiagramObject.Update();
						}
					}
				}
				currentDiagram.DiagramObjects.Refresh();

				repository.GetProjectInterface().LayoutDiagramEx(currentDiagram.DiagramGUID,0,4,20,20,true);
				repository.SaveDiagram(currentDiagram.DiagramID);
				repository.CloseDiagram(currentDiagram.DiagramID);

				repository.EnableUIUpdates = true;

			}
			catch(Exception exception)
			{
                MessageBox.Show("CreateDataSetDiagram -- " + exception, "CreateDataSetDiagram Exception");
                returnString = "";
			}
			
			return returnString;

		}

	}
}
